package com.xyw.his00.controller;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.xyw.his00.config.AlipayConfig;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.json.JSONObject;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import java.io.*;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
@CrossOrigin(origins = "http://localhost:5173")
@RestController
@RequestMapping("/alipay")
@Transactional(rollbackFor = Exception.class)
//出现这个异常就回滚事务 默认情况下只有出现RuntiemException才回滚异常。rollbackFor属性用于控制出现何种异常类型，回滚事务
public class AliPayController {
    @Resource
    private AlipayClient alipayClient;
    @Resource
    private AlipayConfig alipayConfig;


    @PostMapping("/pay")
    public Map<String, Object> pay(HttpServletRequest httpServletRequest,
                                   @RequestBody Map<String, String> params) throws AlipayApiException, UnsupportedEncodingException {
        //System.out.println("pay方法执行");
        //回调地址时带上token
        //String token=httpServletRequest.getHeader("token");
        String baseUrl="http://localhost:5173/outerContainer/regist/order";
        //todo:为什么要编码
        //转换成安全传输格式
        //  String encodedToken=URLEncoder.encode(token, StandardCharsets.UTF_8);
        //String returnURL=baseUrl+"?token="+encodedToken;
        // 创建支付请求
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setReturnUrl(params.getOrDefault("return_url", baseUrl)); // 支付成功后同步回调地址
        request.setNotifyUrl(params.getOrDefault("notify_url", "http://a4upvj.natappfree.cc/alipay/notify")); // 支付成功后的异步后端通知地址
        // 设置业务参数
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", params.get("out_trade_no"));
        bizContent.put("total_amount", params.get("total_amount"));
        bizContent.put("subject", params.get("subject"));
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
        request.setBizContent(bizContent.toString());
        // 发送请求并获取响应
        String form = alipayClient.pageExecute(request).getBody();
        // 返回表单数据给前端
        Map<String, Object> result = new HashMap<>();
        result.put("form", form);
        return result;
    }
     //同步回调:支付宝通常会将查询参数附加在URL的查询字符串中，不是作为POST请求的请求体发送
     @GetMapping("/return")
     public ResponseEntity<Map<String, Object>> handleReturnUrl(HttpServletRequest request) throws AlipayApiException {
         System.out.println("同步回调执行");
         System.out.println(alipayConfig.getAlipayPublicKey());
         Map<String, String> params = new HashMap<>();
         Map<String, String[]> requestParams = request.getParameterMap();
         for (Map.Entry<String, String[]> entry : requestParams.entrySet()) {
             if (entry.getValue().length > 0) {
                 params.put(entry.getKey(), entry.getValue()[0]);
             }
         }
         boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), "UTF-8", "RSA2");
         Map<String, Object> result = new HashMap<>();
         result.put("payResult", signVerified && "TRADE_SUCCESS".equals(params.get("trade_status")));
         // 返回一个 JSON 响应给前端
         return ResponseEntity.ok(result);
     }
    @PostMapping("/notify")
    @ResponseBody
    public String handleNotifyUrl(@RequestBody String notifyData) throws AlipayApiException, IOException {
        System.out.println("异步回调执行");
        // 将请求体转换为 Map
        Map<String, String> params = convertQueryToMap(notifyData); // 修改或创建这个方法

        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), "UTF-8", "RSA2");
        if (signVerified) {
            // 处理支付成功的逻辑
            String outTradeNo = params.get("out_trade_no");
            String tradeNo = params.get("trade_no");
            String tradeStatus = params.get("trade_status");

            if ("TRADE_SUCCESS".equals(tradeStatus)) {
//                // 更新订单状态为已支付
//                updateOrderStatus(outTradeNo, tradeNo);

                // 返回 success 给支付宝
                return "success";
           }
        }
        // 如果验证失败或处理失败，返回 failure
        return "failure";
    }

    // 新增方法，用于将URL编码的表单数据字符串解析为Map
    private Map<String, String> convertQueryToMap(String query) throws UnsupportedEncodingException {
        String[] pairs = query.split("&");
        Map<String, String> result = new HashMap<>();
        for (String pair : pairs) {
            int idx = pair.indexOf('=');
            if (idx > 0) {
                String key = URLDecoder.decode(pair.substring(0, idx), "UTF-8");
                String value = URLDecoder.decode(pair.substring(idx + 1), "UTF-8");
                result.put(key, value);
            }
        }
        return result;
    }
   //新增方法，用于将输入流转换成map<String,String>类
    private Map<String, String> convertStreamToStringMap (InputStream inputStream) throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();

            Map<String, String> map = new HashMap<>();
            for (String param : sb.toString().split("&")) {
                String[] keyValue = param.split("=");
                if (keyValue.length == 2) {
                    map.put(keyValue[0], keyValue[1]);
                }
            }
            return map;
        }


    }